package com.travel.mapper.service;

import com.travel.model.dto.service.ServiceDTO;
import com.travel.model.entity.content.Comment;
import com.travel.model.entity.service.Service;
import org.apache.ibatis.annotations.*;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;
//团购服务mapper 查询服务 插入服务 更新服务 删除服务
@Mapper
@Repository
public interface ServiceMapper {
    
    @Select("SELECT * FROM services WHERE id = #{id}")
    Optional<Service> findById(@Param("id") Long id);
    
    @Select("SELECT * FROM services WHERE type = #{type}")
    List<Service> findByType(@Param("type") String type);
    
    @Select("SELECT * FROM services WHERE city = #{city}")
    List<Service> findByCity(@Param("city") String city);
    
    @Select("SELECT * FROM services WHERE city = #{city} AND type = #{type}")
    List<Service> findByCityAndType(@Param("city") String city, @Param("type") String type);
    
    @Insert("INSERT INTO services (name, description, type, price, city, address, " +
            "contact_info, details, status, image_url, user_id, created_time, updated_time) " +
            "VALUES (#{name}, #{description}, #{type}, #{price}, #{city}, #{address}, " +
            "#{contactInfo}, #{details}, #{status}, #{imageUrl}, #{userId}, #{createdTime}, #{updatedTime})")
    @Options(useGeneratedKeys = true, keyProperty = "id")
    int save(Service service);
    
    @Update("UPDATE services SET name = #{name}, description = #{description}, " +
            "type = #{type}, price = #{price}, city = #{city}, address = #{address}, " +
            "contact_info = #{contactInfo}, details = #{details}, status = #{status}, " +
            "image_url = #{imageUrl}, updated_time = #{updatedTime} WHERE id = #{id}")
    int update(Service service);
    
    @Delete("DELETE FROM services WHERE id = #{id}")
    int delete(Service service);
    
    @Select("SELECT * FROM services")
    List<Service> findAll();
    
    @Select("SELECT * FROM services WHERE status = #{status}")
    List<Service> findByStatus(@Param("status") Integer status);
    
    @Select("SELECT * FROM services WHERE user_id = #{userId}")
    List<Service> findByUserId(@Param("userId") Long userId);
    
    @Select("SELECT c.*, " +
            "u.nickname as user_nickname, " +
            "u.avatar as user_avatar, " +
            "u.status as user_status " +
            "FROM comments c " +
            "LEFT JOIN users u ON c.user_id = u.id " +
            "WHERE c.target_id = #{serviceId} " +
            "AND c.target_type = 'SERVICE' " +
            "AND c.status = 1")
    @Results({
        @Result(property = "id", column = "id"),
        @Result(property = "content", column = "content"),
        @Result(property = "userId", column = "user_id"),
        @Result(property = "targetId", column = "target_id"),
        @Result(property = "targetType", column = "target_type"),
        @Result(property = "rating", column = "rating"),
        @Result(property = "status", column = "status"),
        @Result(property = "createdTime", column = "created_time"),
        @Result(property = "updatedTime", column = "updated_time"),
        @Result(property = "user.id", column = "user_id"),
        @Result(property = "user.nickname", column = "user_nickname"),
        @Result(property = "user.avatar", column = "user_avatar"),
        @Result(property = "user.status", column = "user_status")
    })
    List<Comment> findServiceComments(@Param("serviceId") Long serviceId);
    
    default ServiceDTO toDTO(Service service) {
        if (service == null) {
            return null;
        }
        ServiceDTO dto = new ServiceDTO();
        dto.setId(service.getId());
        dto.setName(service.getName());
        dto.setDescription(service.getDescription());
        dto.setType(service.getType());
        dto.setPrice(service.getPrice());
        dto.setCity(service.getCity());
        dto.setAddress(service.getAddress());
        dto.setContactInfo(service.getContactInfo());
        dto.setDetails(service.getDetails());
        dto.setStatus(service.getStatus());
        dto.setImageUrl(service.getImageUrl());
        
        Double avgRating = getAverageRating(service.getId());
        Integer commentCount = getCommentCount(service.getId());
        dto.setAverageRating(avgRating);
        dto.setCommentCount(commentCount);
        
        return dto;
    }
    
    default Service toEntity(ServiceDTO dto) {
        if (dto == null) {
            return null;
        }
        Service service = new Service();
        service.setId(dto.getId());
        service.setName(dto.getName());
        service.setDescription(dto.getDescription());
        service.setType(dto.getType());
        service.setPrice(dto.getPrice());
        service.setCity(dto.getCity());
        service.setAddress(dto.getAddress());
        service.setContactInfo(dto.getContactInfo());
        service.setDetails(dto.getDetails());
        service.setImageUrl(dto.getImageUrl());
        return service;
    }
    
    default void updateEntity(ServiceDTO dto, Service service) {
        if (dto == null) {
            return;
        }
        service.setName(dto.getName());
        service.setDescription(dto.getDescription());
        service.setType(dto.getType());
        service.setPrice(dto.getPrice());
        service.setCity(dto.getCity());
        service.setAddress(dto.getAddress());
        service.setContactInfo(dto.getContactInfo());
        service.setDetails(dto.getDetails());
        service.setImageUrl(dto.getImageUrl());
    }
    
    @Select("SELECT AVG(rating) FROM comments " +
            "WHERE target_id = #{serviceId} AND target_type = 'SERVICE' AND status = 1")
    Double getAverageRating(@Param("serviceId") Long serviceId);
    
    @Select("SELECT COUNT(*) FROM comments " +
            "WHERE target_id = #{serviceId} AND target_type = 'SERVICE' AND status = 1")
    Integer getCommentCount(@Param("serviceId") Long serviceId);
} 